#!/usr/bin/python3
# -*- coding: UTF-8 -*- 
# 设置utf-8  显示中文
"""
@Create Time: 2021/1/14 下午3:47
@Author: guo
@File：handle_check_data.py
"""
import pytest

from common.util.get_file_path import GetFilePath
from common.yml.get_yml_keys import GetYmlKeys
from config.get_conf_data import GetConfData


class HandleCheckData:
    """"""
    def __init__(self):
        self.__conf = GetConfData()
        self.__cfile = GetFilePath()

    def get_check_data(self,page_api_data:dict,yml_keys:GetYmlKeys,case_api_data:dict=None,req_keys:list=None)->dict:
        """
        处理是否对响应结果的数据进行数据校验,规则如下:   \n
        1: ensure_check 默认值为false   \n
        2: ensure_return 默认值为true(返回该结果)   \n
        3: save_jsonfile_path: 校验书写的正确性   \n
        4: ensure_checktime: 默认值为false   \n
        5: time_type: 默认值为s 共4种类型: s(秒),m(分钟),h(小时),d(天)   \n

        :param page_api_data: 对应的page层的yml里的 api_data 的数据
        :param yml_keys: yml的keys
        :param case_api_data: 传入的case层 yml数据 对应的 api_data的数据
        :param req_keys: 传入的case层的yml数据 对应的key
        :return: dict
        """
        api_data = page_api_data
        yml_keys = yml_keys
        req_params = case_api_data
        req_keys = req_keys

        ensure_check_Key = yml_keys.get_ensure_check_key()
        check_data_key = yml_keys.get_check_data_key()
        check_flag = False
        check_value = None

        if req_keys !=None:
            if ensure_check_Key in req_keys:
                check_value = req_params[ensure_check_Key]

        if check_value == True:
            check_flag = True

        # 进行赋值
        api_data[ensure_check_Key] = check_flag

        # 进行check_data的赋值

        if check_flag == False:
            api_data[check_data_key] = None

        # 表示需要进行数据校验
        else:
            """
            第一步: 通过for循环,将case层的数据,赋值给page层.
            """
            # 先判断check_data_key 是否存在,当不存在时,则将case置为fail
            if check_data_key not in req_keys:
                pytest.fail(f"传入的 {ensure_check_Key} 的值为True,但是未传入 {check_data_key},"
                            f"故将case置为fail.")

            checkdata:dict = req_params[check_data_key]
            for key in checkdata.keys():
                api_data[check_data_key][key] = checkdata[key]

            # *************** 下面设置ensure_return 的代码注释掉了,不在启用该字段*********************
            # """
            # 第二步: 校验ensure_return的值,当不符合要求时,设置默认值
            # ensure_return的默认值为true。
            # 当ensure_return为空时，只有当save_jsonfile_path的值为str时，才会将ensure_return的值设置为true
            # 后期考虑实现自动，当ensure_return为空时，且save_jsonfile_path也为空时，会自动设置save_jsonfile_path的默认值
            # 且将ensure_return的值设置为true
            # """
            # return_key = yml_keys.get_ensure_return_key()
            # # 获取赋值后的check_data的值
            # checkdata = api_data[check_data_key]
            # # 获取ensure_return的值
            # return_value = checkdata[return_key]
            #
            #
            # """
            # 两种判断方式：
            # 方法1：先判断save_jsonfile_path 的值是否为str类型。若不为str类型，此时若ensure_return的值为true，则将case置为fail
            # 若ensure_return 的值为false时，则将ensure_return 的值置为false
            # 方式2：先判断ensure_return的值，当不为false时，均统一置为true。然后再判断save_jsonfile_path的值是否为str
            # 若不为str时，则将case置为fail
            # 后续考虑：当save_jsonfile_path的值的类型不为str时，会自动的替换为与当前case同名，且目录名称与case的目录名称，保存在jsonfile
            # 目录下。如当前的case名称为 test_query,目录相对于ymlfile为 qingjia/web,则会在jsonfile目录下，保存一个
            # qingjia/web/test_query.json 的文件
            # """
            # # 对ensure_return 进行赋值，彩方法2 进行判断(为了保持整体的判断风格一致，所以拆成了两个步骤)
            # flag = True
            #
            # if return_value == False:
            #     flag = False
            #
            # # 进行赋值
            # api_data[check_data_key][return_key] = flag
            #
            # """
            # 此处若要再严谨些，可以校验save_keys 和 query_keys的值是否为空。当有一个为空时，需要将cas置为fial
            # """

            """
            第三步：检查save_jsonfile_path的合法性，若路径中存在jsonfile目录，则会去掉
            该路径的正确的书写方式为：json文件相对于jsonfile目录的路径。
            当校验后，会返回该路径的绝对路径
            """
            # 获取save_jsonfile_path的key值
            save_key = yml_keys.get_save_jsonfile_path_key()
            save_value = checkdata[save_key]

            # # 判断save_value的值
            # if flag == True:
            #     if save_value == None or (not isinstance(save_value, str)):
            #         pytest.fail(f"在进行数据检查时，{return_key} 的值为：{flag} ，但是"
            #                     f"{save_key} 的值为：{save_value}，书写错误。注意格式"
            #                     f"故将该case置为fail")
            #
            #     # 表示save_jsonfile_path 的值为str。此时要进行校验，同时并返回该值的绝对路径
            #     save_value = self.__cfile.get_file_abspath_json(save_value)

            if save_value != None :
                if (not isinstance(save_value, str)):
                    pytest.fail(f"在进行数据检查时，{save_key} 的值为: {save_value},书写不规范,不符合要求."
                                f"{save_key}的值的类型,要么为None,要么为str类型.\n"
                                f"由于书写不规范,故将值置为None.")
                else:
                    # 表示save_jsonfile_path 的值为str。此时要进行校验，同时并返回该值的绝对路径
                    save_value = self.__cfile.get_file_abspath_json(save_value)

            # 进行赋值
            api_data[check_data_key][save_key] = save_value

            """
            第四步：校验ensure_checktime的值，默认为false，不进行时间差值的校验。有时在添加数据后，页面上可能有多条相同的数据
            为了精准的查找出，哪一条是目标数据，就需要有一个时差值。如5秒。当 当前的时间和提交时间的差值在5秒以内，第一条
            查询到的数据，就认为是目标数据。
            """
            # 获取check_data里的check_data 即最内层的check_data的值
            checkdata_second = checkdata[check_data_key]
            # ensure_checktime key
            checktime_key = yml_keys.get_ensure_checktime_key()
            checktime_flag = False
            checktime = checkdata_second[checktime_key]
            # 进行判断
            if checktime == True:
                checktime_flag = True

            # 进行赋值
            api_data[check_data_key][check_data_key][checktime_key] = checktime_flag


            """
            第五步：校验time_type的值，是否为指定的几种值。
            s：秒，m：分钟，h：小时，d：天
            默认值为：s
            """
            timedelta_key = yml_keys.get_time_delta_key()
            if checktime_flag == False:
                api_data[check_data_key][check_data_key][timedelta_key] = None

            # 表示要进行时间差值的校验，此时要检查 time_type的值的书写规范性
            else:
                timedelta_dict = checkdata_second[timedelta_key]
                type_key = yml_keys.get_time_type_key()
                type_value = timedelta_dict[type_key]
                s_str = self.__conf.get_second_str()
                m_str = self.__conf.get_minute_str()
                h_str = self.__conf.get_hour_str()
                d_str = self.__conf.get_day_str()
                time_type = s_str
                if type_value == None or (not isinstance(type_value,str)):
                    time_type = time_type
                else:
                    type_value = str.lower(type_value)
                    if d_str in type_value:
                        time_type = d_str
                    elif h_str in type_value:
                        time_type = h_str
                    elif m_str in type_value:
                        time_type = m_str
                    else:
                        time_type = s_str
                # 进行赋值
                api_data[check_data_key][check_data_key][timedelta_key][type_key] = time_type

        # 返回值
        return api_data
